﻿using System;
using System.Collections.Generic;
using States = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitState.States;
using Types = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitType.Types;

namespace Eflong.Monitor
{
    /*
     * ["0态", "1态", "2态", "正常", "超下限", "超上限", "负漂", "溢出", "断线", "通信中断", "未知"];
     *  public static const State0:uint = 0;
		public static const State1:uint = 1;
		public static const State2 : uint = 2;

		// 新增 统计故障的状态

		public static const State3 : uint = 3;
		public static const Normal : uint  = 0x10;
		public static const UnderLowerLimit : uint = 0x11 ;
		public static const OverUpperLimit : uint = 0x12 ;
		public static const Underflow : uint = 0xfa;
		public static const Overflow : uint = 0xfb;
		public static const Break : uint = 0xfe;
		public static const Halt : uint = 0xff;
		public static const UnknownState : uint = 0x80;
     *
     * 还应该考虑 不扫描,
     */

    //public enum States
    //{
    //    State0 = 0,  // 正常
    //    State1 = 1,  // 异常
    //    State2 = 2,  // 故障???

    //    Normal = 16,
    //    UnderLowerLimit = 17,
    //    OverUpperLimit = 18,
    //    Underflow = 0xfa,
    //    Overflow = 0xfb,
    //    Break = 0xfe,
    //    Halt = 0xff,
    //    UnknownState = 0x80
    //}

    /// <summary>
    ///  传感器报警信息
    /// </summary>
    public class SensorAlertInfo : SensorInfo
    {
        /// <summary>
        /// 传感器报警值
        /// </summary>
        public float fAlertValue;

        /// <summary>
        /// 传感器解除值
        /// </summary>
        public float fRelievedValue;

        /// <summary>
        /// 报警、解除状态
        /// </summary>
        public string sValue;

        /// <summary>
        /// 报警最大值
        /// </summary>
        public float fMaxValue;

        /// <summary>
        /// 报警最大时刻
        /// </summary>
        public DateTime tmMaxValue;

        /// <summary>
        /// 报警最小值
        /// </summary>
        public float fMinValue;

        /// <summary>
        /// 报警最小时刻
        /// </summary>
        public DateTime tmMinValue;

        /// <summary>
        ///  平均值
        /// </summary>
        public float fAvgValue;

        // sum
        private float fSumValue;

        // sum count
        private float fSumCount;

        /// <summary>
        ///  报警次数
        /// </summary>
        public Int32 nAlertCount;

        /// <summary>
        /// 报警时长
        /// </summary>
        public float fAlertTime;

        /// <summary>
        /// 组合报警的字典
        /// </summary>
        public Dictionary<int , CompositeAlertInfo> dic_CompositeAlertInfo = new Dictionary<int , CompositeAlertInfo>( );

        public SensorAlertInfo( )
        {
            CoalMineId = 0;
            fMaxValue = -10000;
            fMinValue = 10000;
            fAvgValue = 0;
            nAlertCount = 0;
            fAlertTime = 0;
            fSumValue = 0;
            fSumCount = 0;
            IsAlert = false;
            IsRecord = false;
            IsFinish = false;

            list_AutoId = new List<Int32>( );
        }

        public SensorAlertInfo Clone( )
        {
            return this.MemberwiseClone( ) as SensorAlertInfo;
        }

        /// <summary>
        /// 对初次报警记录进行设置
        /// </summary>
        public SensorAlertInfo SetupInfo( ExcessRecord er )
        {
            Init( er );
            State = er.State;
            Value = er.Value;
            if ( ( er.State >= States.UnderLowerLimit ) && ( er.State <= States.OverTiming ) )
            {
                // 新报警
                fAlertValue = er.Value;
                tmStart = er.Time;
                fMinValue = er.Value;
                tmMinValue = er.Time;
                fMaxValue = er.Value;
                fAvgValue = er.Value;
                tmMaxValue = er.Time;
                nAlertCount = 1;

                IsAlert = true;
                if ( tmStart >= DateTime.Today )
                {
                    // 今天的模拟量报警.才需要记录
                    IsNeedRecord = true;
                }

                IsRecord = false;

                fSumValue = er.Value;
                fSumCount = 1;
                tmStop = er.Time;
                fRelievedValue = er.Value;
            }
            else
            {
                if ( er.State == States.State1 || er.State == States.State2 )
                {
                    // 异常状态,风机一般是停  风门一般是开
                    IsAlert = true;
                    tmStart = er.Time;
                    nAlertCount = 1;
                    if ( er.Time >= DateTime.Today )
                    {
                        // 今天的开关量报警,需要记录

                        IsNeedRecord = true;
                    }
                    tmStop = er.Time;
                    IsRecord = false;
                }
                else if ( er.State == States.State0 )
                {
                    //IsAlert = false;
                    //tmStop = er.Time;
                    throw new Exception( "开关量没有报警" );
                }
            }

            list_AutoId.Add( er.AutoId );

            return this;
        }

        /// <summary>
        /// 校验传感器的类型及状态是否有效
        /// </summary>
        /// <param name="er"></param>
        /// <returns></returns>
        public bool ValidCheck( ExcessRecord er )
        {
            // 是否考虑传感器的类型的改变??
            if ( this.sType.Equals( er.MonUnitType ) == false )
            {
                // throw new Exception("类型改变");
                return false;
            }

            // 考虑类型与状态的不一致?  从开关量变成模拟量

            if ( this.Modality == Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital )
            {
                if ( ( er.State >= States.UnderLowerLimit ) && ( er.State <= States.OverUpperLimit ) )
                {
                    // throw new Exception("类型与状态不一致");
                    return false;
                }
            }
            else
            {
                if ( er.State <= States.State2 && er.State >= States.State0 )
                {
                    // throw new Exception("类型与状态不一致");
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 更新报警信息
        /// </summary>
        public const int Alert_Delay_time = 5;  // 30秒

        /// <summary>
        /// 更新报警信息
        /// </summary>
        /// <param name="er"></param>
        /// <returns></returns>
        public SensorAlertInfo UpdateAlertInfo( ExcessRecord er )
        {
            if ( ValidCheck( er ) )
            {
                // 更新原因及措施

                UpdateInfo( er );

                IsUpdate = true;
                tmUpdate = er.Time;
                Value = er.Value;

                if ( tmUpdate >= DateTime.Today )
                {
                    //超过今天临晨,并且持续时间超过30秒 , 应该当作当前报警了,
                    // 主要是模拟量有多次更新,
                    // 开关量一般只有一次报警记录,或者零点时,也有更新
                    if ( this.Modality == Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital || tmUpdate.Subtract( tmStart ).TotalSeconds >= Alert_Delay_time )
                    {
                        IsNeedUpdate = true;
                        IsNeedRecord = true;
                    }
                }
                if ( this.Modality != Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital )
                {
                    if ( ( er.State >= States.UnderLowerLimit ) && ( er.State <= States.OverTiming ) )
                    {
                        // 继续报警
                        if ( er.Value > fMaxValue )
                        {
                            fMaxValue = er.Value;
                            tmMaxValue = er.Time;
                        }
                        if ( er.Value < fMinValue )
                        {
                            fMinValue = er.Value;
                            tmMinValue = er.Time;
                        }
                        fSumValue += er.Value;
                        fSumCount += 1;
                        if ( fSumCount > 1 )
                        {
                            fAvgValue = fSumValue / fSumCount;
                        }
                        else
                        {
                            fAvgValue = fMaxValue;
                        }
                        tmStop = er.Time;
                        fRelievedValue = er.Value;
                        list_AutoId.Add( er.AutoId );
                    }
                    if ( ( IsAlert ) && ( er.State == States.Normal || er.State == States.UnderRestLimit ) )
                    {
                        // 解除报警了

                        IsBreak = false;
                        IsAlert = false;
                        tmStop = er.Time;
                        fRelievedValue = er.Value;
                        double dt = tmStop.Subtract( tmStart ).TotalSeconds;

                        fAlertTime = ( float )dt / 60;

                        // 报警记录结束
                        IsFinish = true;
                        list_AutoId.Add( er.AutoId );
                    }
                }
                else if ( this.Modality == Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital )
                {
                    if ( er.State == States.State2 || er.State == States.State1 )
                    {
                        // 异常
                        //IsAlert = true;
                        // tmStart = er.Time;
                        //nAlertCount = 1;
                        //throw new Exception("开关量已经报警了");
                        // 当故障解除时,也会再次记录
                    }
                    else if ( er.State == States.State0 )
                    {
                        // 正常
                        IsAlert = false;
                        tmStop = er.Time;

                        //double dt = tmStop.Subtract(tmStart).TotalSeconds;// (float)dt / 60;
                        fAlertTime = ( float )tmStop.Subtract( tmStart ).TotalMinutes;

                        // 报警记录结束
                        IsFinish = true;
                    }
                    list_AutoId.Add( er.AutoId );
                }
            }
            return this;
        }

        /// <summary>
        /// 通信故障,结束报警
        /// </summary>
        /// <param name="er"></param>
        /// <returns></returns>
        public SensorAlertInfo AlertInfoEndByFault( ExcessRecord er )
        {
            //
            ValidCheck( er );

            // 更新原因及措施

            UpdateInfo( er );

            IsUpdate = true;
            tmUpdate = er.Time;
            if ( tmUpdate >= DateTime.Today )
            {
                //超过今天临晨,并且持续时间超过30秒 , 应该当作当前报警了,
                // 主要是模拟量有多次更新,
                // 开关量一般只有一次报警记录,或者零点时,也有更新
                if ( this.Modality == Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital || tmUpdate.Subtract( tmStart ).TotalSeconds >= Alert_Delay_time )
                {
                    IsNeedUpdate = true;
                    IsNeedRecord = true;
                }
            }
            if ( this.Modality != Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital )
            {
                if ( IsAlert )
                {
                    // 解除报警了

                    IsAlert = false;
                    tmStop = er.Time;

                    //fRelievedValue = er.Value;
                    double dt = tmStop.Subtract( tmStart ).TotalSeconds;

                    fAlertTime = ( float )dt / 60;

                    // 报警记录结束
                    IsFinish = true;
                    list_AutoId.Add( er.AutoId );
                }
            }
            else if ( this.Modality == Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital )
            {
                if ( er.State == States.State2 || er.State == States.State1 )
                {
                    // 异常
                    //IsAlert = true;
                    // tmStart = er.Time;
                    //nAlertCount = 1;
                    //throw new Exception("开关量已经报警了");
                    // 当故障解除时,也会再次记录
                }
                else
                {
                    // 解除报警
                    IsAlert = false;
                    tmStop = er.Time;
                    double dt = tmStop.Subtract( tmStart ).TotalSeconds;
                    fAlertTime = ( float )dt / 60;

                    // 报警记录结束
                    IsFinish = true;
                }
                list_AutoId.Add( er.AutoId );
            }

            return this;
        }

        /// <summary>
        /// 统计报警信息
        /// </summary>
        /// <param name="info"></param>
        public void StatAlertInfo( SensorAlertInfo info )
        {
            nAlertCount++;
        }

        /// <summary>
        /// 初始化统计报警信息
        /// </summary>
        /// <param name="info"></param>
        public void InitAlertInfo( SensorAlertInfo info )
        {
        }

        /// <summary>
        /// 产生瓦斯传感器
        /// </summary>
        /// <param name="nId"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public static SensorAlertInfo CreateCH4SensorAlertInfo( int nId , string sId )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "瓦斯";
            alertInfo1.sUnit = "%CH4";
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Analog;
            alertInfo1.Name = "2211工作面瓦斯";
            alertInfo1.Type = Types.甲烷;
            alertInfo1.LowerLimit = 0;
            alertInfo1.AlertValue = 1.0f;
            alertInfo1.BreakValue = 1.5f;
            return alertInfo1;
        }

        /// <summary>
        /// 产生一氧化碳传感器
        /// </summary>
        /// <param name="nId"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public static SensorAlertInfo CreateCOSensorAlertInfo( int nId , string sId )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "一氧化碳";
            alertInfo1.sUnit = "ppm";
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Analog;
            alertInfo1.Name = "2211工作面CO";
            alertInfo1.Type = Types.CO;
            alertInfo1.AlertValue = 24.0f;
            return alertInfo1;
        }

        public static SensorAlertInfo CreateTSensorAlertInfo( int nId , string sId )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "温度";
            alertInfo1.sUnit = "°";
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Analog;
            alertInfo1.Name = "2211工作面温度";
            alertInfo1.Type = Types.湿度;
            alertInfo1.AlertValue = 30.0f;
            return alertInfo1;
        }

        /// <summary>
        /// 产生负压传感器
        /// </summary>
        /// <param name="nId"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public static SensorAlertInfo CreateSubpressureSensorAlertInfo( int nId , string sId )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "负压";
            alertInfo1.sUnit = "kpa";
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Analog;
            alertInfo1.Name = "2211工作面负压";
            alertInfo1.Type = Types.负压;
            alertInfo1.AlertValue = 5.0f;
            return alertInfo1;
        }

        /// <summary>
        /// 产生风机传感器
        /// </summary>
        /// <param name="nId"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public static SensorAlertInfo CreateFJSensorAlertInfo( int nId , string sId , string name )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "风机";
            alertInfo1.sUnit = string.Empty;
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital;
            alertInfo1.Name = name;// "大巷风机";
            alertInfo1.Type = Types.风机;
            alertInfo1.ValueDecs = new string[ 3 ] { "开" , "停" , "停" };

            return alertInfo1;
        }

        /// <summary>
        /// 产生主扇传感器
        /// </summary>
        /// <param name="nId"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public static SensorAlertInfo CreateZFJSensorAlertInfo( int nId , string sId , string name )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "主扇";
            alertInfo1.sUnit = string.Empty;
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital;
            alertInfo1.Name = name;// "南风井主扇";
            alertInfo1.Type = Types.主扇;
            alertInfo1.ValueDecs = new string[ 3 ] { "开" , "停" , "停" };

            return alertInfo1;
        }

        /// <summary>
        /// 产生断电传感器
        /// </summary>
        /// <param name="nId"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public static SensorAlertInfo CreateDDSensorAlertInfo( int nId , string sId , string name )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "断电";
            alertInfo1.sUnit = string.Empty;
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital;
            alertInfo1.Name = name;// "南风井主扇";
            alertInfo1.Type = Types.断电;
            alertInfo1.ValueDecs = new string[ 3 ] { "送电" , "断电" , "断电" };

            return alertInfo1;
        }

        /// <summary>
        /// 产生馈电传感器
        /// </summary>
        /// <param name="nId"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public static SensorAlertInfo CreateKDSensorAlertInfo( int nId , string sId , string name )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "馈电";
            alertInfo1.sUnit = string.Empty;
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital;
            alertInfo1.Name = name;// "南风井主扇";
            alertInfo1.Type = Types.馈电;
            alertInfo1.ValueDecs = new string[ 3 ] { "有电" , "无电" , "无电" };

            return alertInfo1;
        }

        /// <summary>
        /// 产生烟雾传感器
        /// </summary>
        /// <param name="nId"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public static SensorAlertInfo CreateYWSensorAlertInfo( int nId , string sId )
        {
            SensorAlertInfo alertInfo1 = new SensorAlertInfo( );
            alertInfo1.CoalMineId = nId;
            alertInfo1.MonUnitId = sId;
            alertInfo1.sType = "烟雾";
            alertInfo1.sUnit = string.Empty;
            alertInfo1.Modality = Eflong.MonitoringLib.MonitoringUnit.MonitoringUnitModality.Modalities.Digital;
            alertInfo1.Name = "大巷烟雾";
            alertInfo1.Type = Types.烟雾;
            alertInfo1.ValueDecs = new string[ 3 ] { "无烟" , "有烟" , "有烟" };

            return alertInfo1;
        }
    }

    /* SELECT [AutoId]
      ,[Time]
      ,[MonUnitId]
      ,[State]
      ,[Value]
      ,[CoalMineId]
      ,[MonUnitName]
      ,[MonUnitType]
      ,[SystemId]
  FROM [KWSystem].[dbo].[ExcessRecordTest] */

    /*
     *
     * SELECT [FeedbackID]
      ,[Time]
      ,[MonUnitID]
      ,[CoalMineID]
      ,[CoalMineState]
      ,[FeedbackInfo]
      ,[Idea]
      ,[AnalyseInfo]
      ,[MonType]
      ,[feedbackinfo_clcs]
      ,[MonUnitType]
      ,[AutoId]
      ,[SystemID]
  FROM [KWSystem].[dbo].[ExcessRecordFeedbackInfo]
     *
     *
     */
}